﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Description;
using FANUC.DTO;

namespace FANUC.Controllers
{
    public class TodayAllRobotsStopInMinutesPerHourController : ApiController
    {
        private FANUCDB db = new FANUCDB();
        private Dictionary<int, int> distributeDownTimeMinutesIntoEachHourOfOneDay(DateTime beginTime, DateTime endTime)
        {
            if (endTime < beginTime)
            { throw new Exception("endTime should not smaller than beginTime"); }
            if ((beginTime.DayOfYear == endTime.DayOfYear && beginTime.Year == endTime.Year) == false)
            {
                throw new Exception("The beginTime and endTime should be within one day");
            }
            Dictionary<int, int> EachHourDownTimeMinutes = new Dictionary<int, int>();
            TimeSpan totalTimeSpan = endTime - beginTime;
            int beginTimeHour = beginTime.Hour;
            int endTimeHour = endTime.Hour;
            TimeSpan timeSpanBetweenNextHourAndBeginTime = new DateTime(beginTime.Year, beginTime.Month, beginTime.Day, beginTime.Hour + 1, 0, 0) - beginTime;
            if (timeSpanBetweenNextHourAndBeginTime < totalTimeSpan)
            {
                EachHourDownTimeMinutes.Add(beginTimeHour, Convert.ToInt16(timeSpanBetweenNextHourAndBeginTime.TotalMinutes));
                TimeSpan timeSpanRemaining = endTime - new DateTime(beginTime.Year, beginTime.Month, beginTime.Day, beginTime.Hour + 1, 0, 0);
                TimeSpan timeSpanOfLastHour = endTime - new DateTime(endTime.Year, endTime.Month, endTime.Day, endTime.Hour, 0, 0);
                if (timeSpanOfLastHour < timeSpanRemaining)
                {
                    EachHourDownTimeMinutes.Add(endTime.Hour, Convert.ToInt16(timeSpanOfLastHour.TotalMinutes));
                    int newCycleStartHour = beginTimeHour + 1;
                    for (int i = newCycleStartHour; i < endTime.Hour; i++)
                    {
                        EachHourDownTimeMinutes.Add(i, 60);
                    }
                }
                else
                {
                    EachHourDownTimeMinutes.Add(endTime.Hour, timeSpanRemaining.Minutes);
                }
            }
            else
            {
                EachHourDownTimeMinutes.Add(beginTimeHour, totalTimeSpan.Minutes);
            }
            return EachHourDownTimeMinutes;
        }

        [ResponseType(typeof(TodayAllRobotsStopTotalMinitesByHoursBarDtoOutput))]
        public IHttpActionResult Get()
        {
            #region Test
            if (Helper.IsTest)
            {
                TodayAllRobotsStopTotalMinitesByHoursBarDtoOutput testData = new TodayAllRobotsStopTotalMinitesByHoursBarDtoOutput();
                testData.Date = System.DateTime.Now.Date;
                testData.BarsInfo = new List<decimal>() { 0, 0, 0, 0, 0, 0, 0, 0, 100M, 20M, 33M, 24M, 0, 0, 0, 30M, 20M, 60M, 0, 0, 0, 0, 0, 0 };

                return Ok(testData);
            }
            #endregion
            DateTime today = System.DateTime.Now.Date;
            DateTime tomorrow = today.AddDays(1);
            DateTime now = System.DateTime.Now;

            TodayAllRobotsStopTotalMinitesByHoursBarDtoOutput data = new TodayAllRobotsStopTotalMinitesByHoursBarDtoOutput();
            data.Date = today;
            data.BarsInfo = new List<decimal>() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ;
            var allRobots = db.Robot.ToList();
            foreach (var robot in allRobots)
            {
                List<Robot_State_Change_History> todayAllRobotStateChanges = db.Robot_State_Change_History.Where(a => a.Robot_ID == robot.ID && a.ChangeDateTime >= today && a.ChangeDateTime < tomorrow).OrderBy(a => a.ChangeDateTime).ToList();
                if (todayAllRobotStateChanges.Count <= 0)
                {
                    for (int i = 0; i < now.Hour - 1; i++)
                    {
                        data.BarsInfo[i] = 60;
                    }
                    data.BarsInfo[now.Hour - 1] = now.Minute;
                    return Ok(data);
                }

                DateTime perviousChangeDateTime = today;
                for (int i = 0; i < todayAllRobotStateChanges.Count; i++)
                {
                    if (todayAllRobotStateChanges[i].Changed_State_Type == 4)
                    {
                        perviousChangeDateTime = todayAllRobotStateChanges[i].ChangeDateTime;
                        continue;
                    }

                    Dictionary<int, int> distributionOfThisChange = distributeDownTimeMinutesIntoEachHourOfOneDay(perviousChangeDateTime, todayAllRobotStateChanges[i].ChangeDateTime);
                    foreach (var item in distributionOfThisChange)
                    {
                        data.BarsInfo[item.Key] += item.Value;
                    }
                    perviousChangeDateTime = todayAllRobotStateChanges[i].ChangeDateTime;
                    if (i == todayAllRobotStateChanges.Count - 1)
                    {
                        if (todayAllRobotStateChanges[i].Changed_State_Type != 4)
                        {
                            Dictionary<int, int> distributionOfTheLastChange = distributeDownTimeMinutesIntoEachHourOfOneDay(todayAllRobotStateChanges[i].ChangeDateTime, now);
                            foreach (var item in distributionOfTheLastChange)
                            {
                                data.BarsInfo[item.Key] += item.Value;
                            }
                        }
                    }

                }
            }
                return Ok(data);
        }

        [ApiExplorerSettings(IgnoreApi = true)]
        public string Options()
        { return null; }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
